# ++++++++++ 简介 ++++++++++ #
# 文件名: SpaceSaving.py
# 签名：赵宗义，xinshengzzy@foxmail.com, 2021.01.16
# ---------- #
from simulators.BaseSimulator import BaseSimulator
import mytools
import my_constants as mc
import 文件工具箱
import heapq


class SpaceSaving(BaseSimulator):
    def __init__(self, 内存=1.0):
        super(SpaceSaving, self).__init__()
        self.容量 = int(0.5*内存*1024.0*1024.0/17)
        self.流记录集 = dict()
        self.小顶堆 = []

    def 创建数据结构(self):
        self.哈希表 = [0]*(self.表长1 + self.表长2 + self.表长3 + self.表长4)

    def 配置内存方案(self, 内存方案):
        mc.配置内存方案(内存方案)

    def 处理数据包(self, 标识符, 时间戳):
        '''处理一个新到达的数据包'''
        if 标识符 in self.流记录集:
            self.流记录集[标识符] += 1
        elif len(self.流记录集) < self.容量:
            self.流记录集[标识符] = 1
            heapq.heappush(self.小顶堆, (1, 标识符))
        else:  # 我们要考虑替换流记录集中的数据流了
            self.更新流记录集(标识符)

    def 更新流记录集(self, 标识符):
        while True:
            临流长度, 临标识符 = heapq.heappop(self.小顶堆)
            assert(临流长度 <= self.流记录集[临标识符])
            if 临流长度 < self.流记录集[临标识符]:
                heapq.heappush(self.小顶堆, (self.流记录集[临标识符], 临标识符))
            else:  # 临流长度 == self.流记录集[临标识符]
                流长度 = 临流长度 + 1
                del self.流记录集[临标识符]
                self.流记录集[标识符] = 流长度
                heapq.heappush(self.小顶堆, (流长度, 标识符))
                break

    def 备份(self, 文件名):
        备份 = dict()
        备份["流记录集"] = self.流记录集
        文件工具箱.备份数据结构(备份, 文件名)
